package com.wunu.zn.api.appliance.action;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.wx.pay.model.WechatPayVo;
import com.wx.pay.util.HttpRequestUtil;
import com.wx.pay.util.OauthTokenUtil;
import com.wx.pay.util.OrderUtils;
import com.wx.pay.util.RequestHandler;
import com.wx.pay.util.Sha1Util;
import com.wx.pay.util.StringUtil;
import com.wx.pay.util.WechatPayUtil;
import com.wx.pay.util.WechatTradeTypeEnum;
import com.wx.pay.util.WeixinPayUtil;

import common.AppConst;
import common.support.MobileParam;

/**
 * 微信支付Controller
 * 
 * @author kinfeng
 * @since 2016-08-11
 */
@Controller
@RequestMapping("h5/wx")
public class PpmHtvRechargeController {
	private static String baseUrl =  "h5/wx/";;
	public static Logger log = Logger.getLogger(PpmHtvRechargeController.class);
	Lock lock  = new ReentrantLock();
	
/*	 *//**
     * 前往購買
     * @param request
     * @return
     *//*
    @RequestMapping("/goPay")
	public String goPay(HttpServletRequest request, HttpServletResponse response) {
		return baseUrl+"topay";
	}*/
	/**
	 * 微信网页授权获取用户基本信息，先获取 code，跳转 url 通过 code 获取 openId
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/goPay")
	public String  userAuths(MobileParam param,HttpServletRequest request, HttpServletResponse response,
			@RequestParam(value="address",required=false)  String  address ,
			@RequestParam(value="userName",required=false)String userName,
			@RequestParam(value="number",required=false)String number,
			@RequestParam(value="amount",required=false)String amount,			
			@RequestParam(value="phone",required=false) String phone) {
		String orderId = "";
		try {
			
			orderId = OrderUtils.genOrderNo(phone);
			String totalFee = request.getParameter("amount");//上綫更改
			//String totalFee = "0.1";

			// 授权后要跳转的链接
			String backUri =  AppConst.APP_URL + "/h5/wx/toPay";
			backUri = backUri + "?orderId=" + orderId + "&totalFee=" + totalFee;
			// URLEncoder.encode 后可以在backUri 的url里面获取传递的所有参数
			backUri = URLEncoder.encode(backUri, "UTF-8");
			// scope 参数视各自需求而定，这里用scope=snsapi_base
			// 不弹出授权页面直接授权目的只获取统一支付接口的openid
			String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + "appid=" + AppConst.APPID
					+ "&redirect_uri=" + backUri
					+ "&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
			response.sendRedirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			
		}
		return null;
	}
	/**
	 * 微信支付（拿到授权信息执行支付）
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping("/toPay")
	public String toPay(HttpServletRequest request, HttpServletResponse response, Model model) {
		try {
			String orderId = request.getParameter("orderId");
			// 商品描述
			String body = "悟牛网球避震器";
		/*	System.out.println("in toPay,orderId:" + orderId);*/
			String totalFeeStr = request.getParameter("totalFee");
			Float totalFee = 0.0f;
			if (StringUtils.isNotBlank(totalFeeStr)) {
				totalFee = new Float(totalFeeStr);
			}
			// 网页授权后获取传递的参数
			String code = request.getParameter("code");
			// 获取统一下单需要的openid
			String openId = OauthTokenUtil.getOpenId(code);
			if(openId==null){
				return null;
			}
//			// 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
//			// 随机数
			String nonce_str = UUID.randomUUID().toString().replaceAll("-", "");
			// 订单生成的机器 IP
			String spbill_create_ip = request.getRemoteAddr();
//			// TODO
			Integer total_fee = Math.round(totalFee * 100);
			RequestHandler reqHandler = new RequestHandler(request, response);
			reqHandler.init(AppConst.APPID, AppConst.SECRET, AppConst.PARTNERKEY);//初始化APPID,SECRET ,商户KEY。商户KEY用来做签名用

			Map<String,String> prepayMap = unifiedorder(body,spbill_create_ip,orderId, totalFee, nonce_str, WechatTradeTypeEnum.JSAPI.getCode(), openId);
			String prepay_id = prepayMap.get("prepay_id");
//			System.out.println("prepay_id:" + prepay_id);
			SortedMap<String, String> finalpackage = new TreeMap<String, String>();
			String timestamp = Sha1Util.getTimeStamp();
			String packages = "prepay_id=" + prepay_id;
			finalpackage.put("appId", AppConst.APPID);
			finalpackage.put("timeStamp", timestamp);
			finalpackage.put("nonceStr", nonce_str);
			finalpackage.put("package", packages);
			finalpackage.put("signType", AppConst.signType);
			String finalsign = reqHandler.createSign(finalpackage);
	/*		System.out.println("/jsapi?appid=" + AppConst.APPID + "&timeStamp=" + timestamp + "&nonceStr=" + nonce_str
					+ "&package=" + packages + "&sign=" + finalsign);*/
			model.addAttribute("appid", AppConst.APPID);
			model.addAttribute("timeStamp", timestamp);
			model.addAttribute("nonceStr", nonce_str);
			model.addAttribute("packageValue", packages);
			model.addAttribute("sign", finalsign);
			model.addAttribute("bizOrderId", orderId);
			model.addAttribute("orderId", orderId);
			model.addAttribute("payPrice", total_fee);
			return "/h5/wx/jsapi";
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 微信异步回调，不会跳转页面
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping("/notifyUrl")
	public String weixinReceive(HttpServletRequest request, HttpServletResponse response, Model model) {
		System.out.println("==开始进入h5支付回调方法==");
		String xml_review_result = WeixinPayUtil.getXmlRequest(request);
		System.out.println("微信支付结果:" + xml_review_result);
		Map resultMap = null;
		try {
			resultMap = WeixinPayUtil.doXMLParse(xml_review_result);
			System.out.println("resultMap:" + resultMap);
			if (resultMap != null && resultMap.size() > 0) {
				String sign_receive = (String) resultMap.get("sign");
				System.out.println("sign_receive:" + sign_receive);
				resultMap.remove("sign");
				String checkSign = WeixinPayUtil.getSign(resultMap, AppConst.PARTNERKEY);
				System.out.println("checkSign:" + checkSign);
				// 签名校验成功
				if (checkSign != null && sign_receive != null && checkSign.equals(sign_receive.trim())) {
					System.out.println("weixin receive check Sign sucess");
					try {
						// 获得返回结果
						String return_code = (String) resultMap.get("return_code");
						if ("SUCCESS".equals(return_code)) {
							String out_trade_no = (String) resultMap.get("out_trade_no");
							System.out.println("weixin pay sucess,out_trade_no:" + out_trade_no);
					/*    	OrderEntity order = OrderEntity.findOrder(out_trade_no);
					    	if(order!=null){
					    		order.set("payState", true);
					    		int flag = Db.update(order);
					    		if(flag==1){
					    			String openId = order.getStr("openId");
					    			Double amounts = order.getDouble("amounts");
					    			UserEntity user = UserEntity.findByOpenId(openId);
					    			user.set("coin", amounts*AppConst.EXCHANGE_RATIO +user.getInt("coin"));
					    			int result = Db.update(user);
					    			if(result==1){
										model.addAttribute("payResult", "0");
										model.addAttribute("err_code_des", "通信错误");
					    			}
					    		}
					    		
					    	}*/
						} else {
							model.addAttribute("payResult", "0");
							model.addAttribute("err_code_des", "通信错误");
						}
					} catch (Exception e) {
						e.printStackTrace();
						}
				} else {
					// 签名校验失败
					System.out.println("weixin receive check Sign fail");
					String checkXml = "<xml><return_code><![CDATA[FAIL]]></return_code>"
							+ "<return_msg><![CDATA[check sign fail]]></return_msg></xml>";
					 WeixinPayUtil.getTradeOrder(baseUrl+"/fm/order/notifyUrl", checkXml);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 页面js返回支付成功后，查询微信后台是否支付成功，然后跳转结果页面
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("/success")
	public String toWXPaySuccess(HttpServletRequest request, HttpServletResponse response, Model model)
			throws IOException {
		String id = request.getParameter("orderId");
		/*System.out.println("toWXPaySuccess, orderId: " + id);*/
		try {
			Map<String,String> resultMap = WeixinPayUtil.checkWxOrderPay(id);
			/*System.out.println("resultMap:" + resultMap);*/
			String return_code = (String) resultMap.get("return_code");
			String result_code = (String) resultMap.get("result_code");
			if ("SUCCESS".equals(return_code)) {
				if ("SUCCESS".equals(result_code)) {
					
					/*Map<String, Object> wxInfo =  WxPayMain.finByOrderID(id);
					if(wxInfo!=null){
						int result = WxPayMain.update(wxInfo.get("id").toString());
						if(result!=1){
							log.error("WeixinPayController/success ：更新成功标记失败");
						}else{
						model.addAttribute("orderId", id);
						model.addAttribute("payResult", "1");
						model.addAttribute("address", wxInfo.get("address"));
						model.addAttribute("userName", wxInfo.get("name"));
						model.addAttribute("number", wxInfo.get("number"));
						model.addAttribute("amount", wxInfo.get("amount"));
						model.addAttribute("phone", wxInfo.get("phone"));
						}
					}*/
				} else {
					String err_code = (String) resultMap.get("err_code");
					String err_code_des = (String) resultMap.get("err_code_des");
			/*		System.out.println("weixin resultCode:" + result_code + ",err_code:" + err_code + ",err_code_des:"
							+ err_code_des);*/
					System.out.println("isSuccess:FALSE");
					model.addAttribute("err_code", err_code);
					model.addAttribute("err_code_des", err_code_des);
					model.addAttribute("payResult", "0");
				}
			} else {
				model.addAttribute("payResult", "0");
				model.addAttribute("err_code_des", "通信错误");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "/h5/wx/paysuccess";
	}

	/**
	 * 统一下单获取prepay_id
	 * @param orderId
	 * @param totalFee
	 * @param remark
	 * @param tradeType
	 * @param openid
	 * @return
	 */
	private Map<String,String> unifiedorder(String body, String spbillCreateIp ,String orderId, double totalFee, String remark, String tradeType, String openid){
		log.debug("unifiedorder begin...："+openid);
		String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		String notifyUrl = AppConst.APP_URL+"/h5/wx/notifyUrl";
		int orderAmount = (int)(totalFee * 100D);//微信以分为单位
		WechatPayVo wechatPayVo = new WechatPayVo();
		wechatPayVo.setAppid(AppConst.APPID);
		wechatPayVo.setMch_id(AppConst.PARTNER);
		wechatPayVo.setSpbill_create_ip(spbillCreateIp);
		wechatPayVo.setNotify_url(notifyUrl);
		wechatPayVo.setBody(body);
		wechatPayVo.setAppSecret(AppConst.SECRET);
		wechatPayVo.setSignatureKey(AppConst.PARTNERKEY);
		wechatPayVo.setUnifiedorderUrl(url);
		log.debug("unifiedorder WechatPayVo:"+wechatPayVo.getAppid()+","+wechatPayVo.getAppSecret());
		
		String reqXml = WechatPayUtil.buildPayXml(orderId, String.valueOf(orderAmount) , remark, tradeType, openid, wechatPayVo);
		log.debug("unifiedorder reqXml:"+reqXml);
		try {
			HttpRequestUtil http = new HttpRequestUtil(wechatPayVo.getUnifiedorderUrl(), reqXml);
			String resXml = http.post();
			log.debug("unifiedorder resXml:"+resXml);
			Map<String,String> data = StringUtil.xmlToMap(resXml,null);
			if("SUCCESS".equals(data.get("return_code"))){
				if("SUCCESS".equals(data.get("result_code"))){
					return data;
				}else{
					//失败，抛出异常
					String errorInfo = data.get("return_msg");
					throw new RuntimeException(errorInfo);
				}
			}else{
				//失败，抛出异常
				String errorInfo = data.get("return_msg");
				throw new RuntimeException(errorInfo);
			}
		} catch (RuntimeException e) {
			log.error("unifiedorder reqXml:"+reqXml);
			log.error("unifiedorder error ", e);
			throw e;
		} catch (Exception e) {
			log.error("unifiedorder reqXml:"+reqXml);
			throw new RuntimeException(e.getMessage(), e);
		}
	}
}
